package com.dcy.workflow.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import com.dcy.common.annotation.Log;
import com.dcy.common.base.controller.DcyBaseController;
import com.dcy.common.constant.PermissionConstant;
import com.dcy.common.model.R;
import com.dcy.common.utils.satoken.StpAdminUtil;
import com.dcy.workflow.model.FlowNode;
import com.dcy.workflow.service.FlowNodeService;
import com.dcy.workflow.vo.in.FlowNodeSaveInVO;
import com.dcy.workflow.vo.out.FlowNodeListOutVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.ProcessDefinition;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.List;

import static com.dcy.common.constant.TaskConstants.TASK_CANDIDATE_LISTENER_EXP;

/**
 * <p>
 * 流程节点表 前端控制器
 * </p>
 *
 * @author dcy
 * @since 2021-06-08
 */
@RequiredArgsConstructor
@Validated
@RestController
@RequestMapping("/flow/flow-node")
@Api(value = "FlowNodeController", tags = {"流程节点表操作接口"})
public class FlowNodeController extends DcyBaseController {

    private final RepositoryService repositoryService;
    private final FlowNodeService flowNodeService;


    @Log
    @SaCheckPermission(value = PermissionConstant.PROCESS_APPROVE, type = StpAdminUtil.TYPE)
    @ApiOperation(value = "保存")
    @PostMapping(value = "/save")
    public R<Boolean> save(@Validated @ApiParam @RequestBody List<FlowNodeSaveInVO> flowNodeSaveInVOS) {
        return success(flowNodeService.saveFlowNode(flowNodeSaveInVOS));
    }

    @SaCheckPermission(value = PermissionConstant.PROCESS_APPROVE, type = StpAdminUtil.TYPE)
    @ApiOperation(value = "获取活动节点信息")
    @ApiImplicitParam(name = "processDefinitionId", value = "流程定义id", dataType = "String", paramType = "query", required = true)
    @GetMapping(value = "/getActivityListByProDefId")
    public R<List<FlowNodeListOutVO>> getActivityListByProDefId(@NotBlank(message = "流程定义id不能为空") String processDefinitionId) {
        // 查询flowable任务节点信息
        List<FlowNodeListOutVO> list = new ArrayList<>();
        // 获取流程定义对象
        final ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
        // 获取流程图
        final Process process = repositoryService.getBpmnModel(processDefinitionId).getProcessById(processDefinition.getKey());
        final List<UserTask> flowElements = process.findFlowElementsOfType(UserTask.class);
        for (UserTask userTask : flowElements) {
            // 有 ${candidateListener}表达式的监听器
            if (userTask.getTaskListeners().stream().anyMatch(flowableListener ->
                    flowableListener.getImplementation().equals(TASK_CANDIDATE_LISTENER_EXP))) {
                final FlowNode flowNode = flowNodeService.getOntByProcDefIdAndFlowIdAndFlowName(processDefinition.getId(), userTask.getId(), userTask.getName());
                if (flowNode != null) {
                    list.add(new FlowNodeListOutVO(flowNode.getFlowId(),
                            processDefinition.getId(),
                            userTask.getId(),
                            userTask.getName(),
                            flowNode.getFlowType(),
                            flowNodeService.getIds(flowNode))
                    );
                } else {
                    list.add(new FlowNodeListOutVO(
                            processDefinition.getId(),
                            userTask.getId(),
                            userTask.getName())
                    );
                }
            }
        }
        return success(list);

    }

}
